/*
 * Created by 2006-6-30 上午11:05:13
 * $Id: PhotoSpiderFor163.java 88 2006-07-10 17:25:39Z wjx $
 */
package com.someok.service.photo.spider;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;

import com.someok.service.photo.domain.Album163;
import com.someok.service.photo.domain.Photo163;

/**
 * 
 * <p>
 * <a href="PhotoSpiderFor163.java.html"><i>View Source</i></a>
 * </p>
 * 
 * @author wjx
 * @version $Revision: 88 $ $Date: 2006-07-11 01:25:39 +0800 (星期二, 11 七月 2006) $
 */
public class PhotoSpiderFor163 implements PhotoSpider {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger
			.getLogger(PhotoSpiderFor163.class);

	/* 163用户的id. */
	String userId = "";

	public PhotoSpiderFor163(String userId) {
		this.userId = userId;
	}

	/**
	 * 163相册信息所在地址.
	 * 
	 * @return
	 */
	private String getAlbumJsUrl() {
		return "http://photo.163.com/js/albumsinfo.php?user=" + this.userId;
	}

	/**
	 * 163相册的链接生成方式.
	 * 
	 * @param id
	 * @return
	 */
	private String getAlbumUrl(String id) {
		return "http://photo.163.com/photos/" + this.userId + "/" + id;
	}

	/**
	 * 某相册下的图片信息所在地址.
	 * 
	 * @param albumId
	 * @return
	 */
	private String getPhotoInfoJsUrl(String albumId) {
		return "http://photo.163.com/js/photosinfo.php?user=" + this.userId
				+ "&aid=" + albumId;
	}

	/**
	 * 生成缩略图的地址.
	 * @param albumId 相册id
	 * @param domainNum img域名编号
	 * @param photoId 照片id
	 * @return 缩略图url
	 */
	private String getThumbnailUrl(String albumId, String domainNum,
			String photoId) {
		return "http://img" + domainNum + ".photo.163.com/" + this.userId + "/"
				+ albumId + "/__scale__1_" + photoId + ".jpg";
	}
	
	/**
	 * 生成正常大小图片的地址.
	 * @param albumId 相册id
	 * @param domainNum img域名编号
	 * @param photoId 照片id
	 * @return 图片url
	 */
	private String getPhotoUrl(String albumId, String domainNum,
			String photoId) {
		return "http://img" + domainNum + ".photo.163.com/" + this.userId + "/"
		+ albumId + "/" + photoId + ".jpg";
		
	}

	/* (non-Javadoc)
	 * @see com.someok.service.photo.PhotoSpider#forageAlbums()
	 */
	public List forageAlbums() {
		InputStream in = null;
		BufferedReader reader = null;
		List list = null;

		try {
			in = new URL(getAlbumJsUrl()).openStream();

			reader = new BufferedReader(new InputStreamReader(in));

			String line = null;
			String albumsId = null;
			String albumsData = null;
			while ((line = reader.readLine()) != null) {
				if (line.startsWith("var gAlbumsIds")) {
					albumsId = line; // 格式为Js一维数组:[a, b, c]
					albumsId = albumsId.substring(line
							.indexOf("["));
					if (albumsId.endsWith(";")) {
						albumsId = StringUtils.chop(albumsId);
					}
				}

				if (line.startsWith("var datas")) {
					albumsData = line; // 格式为Js二维数组：[[a,b,c],[d,e,f],[h,i,j]]
					albumsData = albumsData.substring(line
							.indexOf("["));
					if (albumsData.endsWith(";")) {
						albumsData = StringUtils.chop(albumsData);
					}
				}
			}

			// 生成相册对象列表
			list = generateAlbumObjList(albumsId, albumsData);

		} catch (MalformedURLException e) {
			logger.error("163相册信息抓取过程中出现异常", e);
			throw new PhotoSpiderException("163相册信息抓取过程中出现异常", e);
		} catch (IOException e) {
			logger.error("163相册信息抓取过程中出现异常", e);
			throw new PhotoSpiderException("163相册信息抓取过程中出现异常", e);
		} finally {
			try {
				reader.close();
				in.close();
			} catch (IOException e) {
				logger.error("Stream关闭过程中出现异常", e);

			}
		}
		return list;
	}

	/**
	 * 根据相册id和内容,生成album对象列表
	 * 
	 * @param albumsId
	 * @param albumsData
	 * @return 相册对象列表
	 */
	private List generateAlbumObjList(String albumsId,
			String albumsData) {
		if (StringUtils.isBlank(albumsId)
				|| StringUtils.isBlank(albumsData)) {
			return null;
		}

		// 将id分解成数组形式
		List albums = new ArrayList();
		try {
			// 相册id和相册内容在js数组里面是一一对应的
			JSONArray idsArr = new JSONArray(albumsId);
			JSONArray dataArr = new JSONArray(albumsData);

			JSONArray tmpArr = null;

			Album163 album = null;
			String album163Id = null;
			String title = null;
			String description = null;
			String url = null;
			int count = 0;
			boolean privacy = false;
			for (int i = 0; i < idsArr.length(); i++) {
				album163Id = idsArr.getString(i); // id

				tmpArr = dataArr.getJSONArray(i);
				title = tmpArr.getString(3);
				description = tmpArr.getString(4);
				url = getAlbumUrl(album163Id);
				count = tmpArr.getInt(2);
				privacy = Album163.isPrivacy(tmpArr.getInt(1));

				// 填充Album对象
				album = new Album163(null, album163Id, title, description, url, count,
						privacy);

				// 置入list
				albums.add(album);
			}
		} catch (JSONException e) {
			logger.error("解析相册信息过程中出现异常", e);
			throw new PhotoSpiderException("解析相册信息过程中出现异常", e);
		}

		return albums;
	}

	/* (non-Javadoc)
	 * @see com.someok.service.photo.PhotoSpider#foragePhotos(java.lang.String)
	 */
	public List foragePhotos(String albumId) {
		InputStream in = null;
		BufferedReader reader = null;
		List list = null;

		try {
			in = new URL(getPhotoInfoJsUrl(albumId)).openStream();

			reader = new BufferedReader(new InputStreamReader(in));

			String line = null;
			String photosId = null;
			String photosData = null;
			while ((line = reader.readLine()) != null) {
				if (line.startsWith("var gPhotosIds")) {
					photosId = line; // 格式为Js一维数组:[a, b, c]
					photosId = photosId.substring(line
							.indexOf("["));
					if (photosId.endsWith(";")) {
						photosId = StringUtils.chop(photosId);
					}
				}

				if (line.startsWith("var datas")) {
					photosData = line; // 格式为Js二维数组：[[a,b,c],[d,e,f],[h,i,j]]
					photosData = photosData.substring(line
							.indexOf("["));
					if (photosData.endsWith(";")) {
						photosData = StringUtils.chop(photosData);
					}
				}
			}

			// 生成相册对象列表
			list = generatePhotoObjList(albumId, photosId, photosData);

		} catch (MalformedURLException e) {
			logger.error("163照片信息抓取过程中出现异常", e);
			throw new PhotoSpiderException("163照片信息抓取过程中出现异常", e);
		} catch (IOException e) {
			logger.error("163照片信息抓取过程中出现异常", e);
			throw new PhotoSpiderException("163照片信息抓取过程中出现异常", e);
		} finally {
			try {
				reader.close();
				in.close();
			} catch (IOException e) {
				logger.error("Stream关闭过程中出现异常", e);

			}
		}
		return list;
	}

	/**
	 * 生成相册对象列表
	 * @param photosId
	 * @param photosData
	 * @param photosData2 
	 * @return
	 */
	private List generatePhotoObjList(String albumId, String photosId, String photosData) {
		if (StringUtils.isBlank(photosId)
				|| StringUtils.isBlank(photosData)) {
			return null;
		}

		// 将id分解成数组形式
		List photos = new ArrayList();
		try {
			// 照片id和照片内容在js数组里面是一一对应的
			JSONArray idsArr = new JSONArray(photosId);
			JSONArray dataArr = new JSONArray(photosData);

			JSONArray tmpArr = null;

			Photo163 photo = null;
			String id = null;
			String photo163Id = null;
			String title = null;
			String description = null;
			String thumbnailUrl = null;
			String url = null;
			String domainNum = null;
			for (int i = 0; i < idsArr.length(); i++) {
				photo163Id = idsArr.getString(i); // id

				tmpArr = dataArr.getJSONArray(i);
				domainNum = tmpArr.getString(0);
				title = tmpArr.getString(3);
				
				thumbnailUrl = getThumbnailUrl(albumId, domainNum, photo163Id);
				url = getPhotoUrl(albumId, domainNum, photo163Id);

				// 填充photo对象
				photo = new Photo163(id, photo163Id, title, description, thumbnailUrl, url, domainNum);
				
				// 置入list
				photos.add(photo);
			}
		} catch (JSONException e) {
			logger.error("解析照片信息过程中出现异常", e);
			throw new PhotoSpiderException("解析照片信息过程中出现异常", e);
		}

		return photos;
	}
}
